package cn.com.spring.model;

import lombok.Data;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * 实体调用
 *
 * @author LiuGuodong
 * @date 2024/02/01
 */
@Data
public class EntityInvocation {

    private Object target;
    private Method method;
    private Object[] args;

    public EntityInvocation(Object target, Method method, Object[] args) {
        this.target = target;
        this.method = method;
        this.args = args;
    }

    /**
     * 执行
     *
     * @return {@link Object}
     * @throws Throwable 可丢弃
     */
    public Object proceed() throws Throwable {
        return method.invoke(target, args);
    }

    public Object proceed(Object[] args) throws Throwable {
        this.args = args;
        return method.invoke(target, args);
    }


    public Object getThis() {
        return target;
    }


    /**
     * 获取目标
     *
     * @return {@link Object}
     */
    public Object getTarget() {
        return target;
    }


    /**
     * 获取参数列表
     *
     * @return {@link Object[]}
     */
    public Object[] getArgs() {
        return args;
    }

    /**
     * get方法
     *
     * @return {@link MethodSignature}
     */
    public MethodSignature getMethod() {
        return new MethodSignature(method);
    }

    /**
     * 方法签名
     *
     * @author LiuGuodong
     * @date 2024/02/01
     */
    public static class MethodSignature {
        private final Method method;

        public MethodSignature(Method method) {
            this.method = method;
        }

        public String getName() {
            return method.getName();
        }

        /**
         * 获取注释
         *
         * @param annotationClass 注释类
         * @return {@link T}
         */
        public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
            return method.getAnnotation(annotationClass);
        }


        public int getModifiers() {
            return method.getModifiers();
        }


        /**
         * 获取声明类型
         *
         * @return {@link Class}<{@link ?}>
         */
        public Class<?> getDeclaringType() {
            return method.getDeclaringClass();
        }


        /**
         * 获取声明类型名称
         *
         * @return {@link String}
         */
        public String getDeclaringTypeName() {
            return method.getDeclaringClass().getName();
        }

        /**
         * 获取返回类型
         *
         * @return {@link Class}
         */
        public Class getReturnType() {
            return method.getReturnType();
        }

    }


}
